(function (window, T) {
    var cookie = T.cookie = {};
    /**
     * 验证字符串是否合法的cookie键名
     * 
     * @param {string} source 需要遍历的数组
     * @meta standard
     * @return {boolean} 是否合法的cookie键名
     */
    cookie._isValidKey = function (key) {
        // http://www.w3.org/Protocols/rfc2109/rfc2109
        // Syntax:  General
        // The two state management headers, Set-Cookie and Cookie, have common
        // syntactic properties involving attribute-value pairs.  The following
        // grammar uses the notation, and tokens DIGIT (decimal digits) and
        // token (informally, a sequence of non-special, non-white space
        // characters) from the HTTP/1.1 specification [RFC 2068] to describe
        // their syntax.
        // av-pairs   = av-pair *(";" av-pair)
        // av-pair    = attr ["=" value] ; optional value
        // attr       = token
        // value      = word
        // word       = token | quoted-string
        
        // http://www.ietf.org/rfc/rfc2068.txt
        // token      = 1*<any CHAR except CTLs or tspecials>
        // CHAR       = <any US-ASCII character (octets 0 - 127)>
        // CTL        = <any US-ASCII control character
        //              (octets 0 - 31) and DEL (127)>
        // tspecials  = "(" | ")" | "<" | ">" | "@"
        //              | "," | ";" | ":" | "\" | <">
        //              | "/" | "[" | "]" | "?" | "="
        //              | "{" | "}" | SP | HT
        // SP         = <US-ASCII SP, space (32)>
        // HT         = <US-ASCII HT, horizontal-tab (9)>
            
        return (new RegExp("^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+\x24")).test(key);
    };


    /**
     * 获取cookie的值，不对值进行解码
     * @name cookie.getRaw
     * @function
     * @grammar cookie.getRaw(key)
     * @param {string} key 需要获取Cookie的键名
     * @meta standard
     * @see cookie.get,cookie.setRaw
     *             
     * @returns {string|null} 获取的Cookie值，获取不到时返回null
     */
    cookie.getRaw = function (key) {
        if (cookie._isValidKey(key)) {
            var reg = new RegExp("(^| )" + key + "=([^;]*)(;|\x24)"),
                result = reg.exec(document.cookie);
                
            if (result) {
                return result[2] || null;
            }
        }

        return null;
    };


    /**
     * 获取cookie的值，用decodeURIComponent进行解码
     * @name cookie.get
     * @function
     * @grammar cookie.get(key)
     * @param {string} key 需要获取Cookie的键名
     * @remark
     * <b>注意：</b>该方法会对cookie值进行decodeURIComponent解码。如果想获得cookie源字符串，请使用getRaw方法。
     * @meta standard
     * @see cookie.getRaw,cookie.set
     *             
     * @returns {string|null} cookie的值，获取不到时返回null
     */
    cookie.get = function (key) {
        var value = cookie.getRaw(key);
        if ('string' == typeof value) {
            value = decodeURIComponent(value);
            return value;
        }
        return null;
    };

    /**
     * 设置cookie的值，不对值进行编码
     * @name cookie.setRaw
     * @function
     * @grammar cookie.setRaw(key, value[, options])
     * @param {string} key 需要设置Cookie的键名
     * @param {string} value 需要设置Cookie的值
     * @param {Object} [options] 设置Cookie的其他可选参数
     * @config {string} [path] cookie路径
     * @config {Date|number} [expires] cookie过期时间,如果类型是数字的话, 单位是毫秒
     * @config {string} [domain] cookie域名
     * @config {string} [secure] cookie是否安全传输
     * @remark
     * 
    <b>options参数包括：</b><br>
    path:cookie路径<br>
    expires:cookie过期时间，Number型，单位为毫秒。<br>
    domain:cookie域名<br>
    secure:cookie是否安全传输
            
     * @meta standard
     * @see cookie.set,cookie.getRaw
     */
    cookie.setRaw = function (key, value, options) {
        if (!cookie._isValidKey(key)) {
            return;
        }
        
        options = options || {};
        //options.path = options.path || "/"; // meizz 20100402 设定一个初始值，方便后续的操作
        //berg 20100409 去掉，因为用户希望默认的path是当前路径，这样和浏览器对cookie的定义也是一致的
        
        // 计算cookie过期时间
        var expires = options.expires;
        if ('number' == typeof options.expires) {
            expires = new Date();
            expires.setTime(expires.getTime() + options.expires);
        }
        
        document.cookie =
            key + "=" + value
            + (options.path ? "; path=" + options.path : "")
            + (expires ? "; expires=" + expires.toGMTString() : "")
            + (options.domain ? "; domain=" + options.domain : "")
            + (options.secure ? "; secure" : ''); 
    };


    /**
     * 设置cookie的值，用encodeURIComponent进行编码
     * @name cookie.set
     * @function
     * @grammar cookie.set(key, value[, options])
     * @param {string} key 需要设置Cookie的键名
     * @param {string} value 需要设置Cookie的值
     * @param {Object} [options] 设置Cookie的其他可选参数
     * @config {string} [path] cookie路径
     * @config {Date|number} [expires] cookie过期时间,如果类型是数字的话, 单位是毫秒
     * @config {string} [domain] cookie域名
     * @config {string} [secure] cookie是否安全传输
     * @remark
     * 
    1. <b>注意：</b>该方法会对cookie值进行encodeURIComponent编码。如果想设置cookie源字符串，请使用setRaw方法。<br><br>
    2. <b>options参数包括：</b><br>
    path:cookie路径<br>
    expires:cookie过期时间，Number型，单位为毫秒。<br>
    domain:cookie域名<br>
    secure:cookie是否安全传输
            
     * @meta standard
     * @see cookie.setRaw,cookie.get
     */
    cookie.set = function (key, value, options) {
        cookie.setRaw(key, encodeURIComponent(value), options);
    };
})(window, T);